NGINX and NGINX Plus can differentiate users based on their geographical location. For example, you can have different website content for different countries, or you can restrict content distribution to a particular country or city.
NGINX uses third-party MaxMind databases to match the IP address of the user and its location. As soon as the geoposition is known, it is then possible to use geoip-based variables in the map or the split_clients module.
Restricting by geographical location works both for http and tcp/udp protocols.
--with-http_geoip_module
and/or --with-stream_geoip_module
configuration flag:
$ nginx -V 2>&1 | grep -- 'http_geoip_module'
$ nginx -V 2>&1 | grep -- 'stream_geoip_module'
Skip this step for NGINX Plus as it already includes geoip modules for http and stream.
$ wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
$ wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
$ gunzip GeoIP.dat.gz
$ gunzip GeoLiteCity.dat.gz
geoip_country
and geoip_city
, or stream’s geoip_country
and geoip_city
directives:
http {
...
geoip_country GeoIP/GeoIP.dat;
geoip_city GeoIP/GeoLiteCity.dat;
...
}
and/or:
stream {
...
geoip_country GeoIP/GeoIP.dat;
geoip_city GeoIP/GeoLiteCity.dat;
...
}
geoip_country
and geoip_city
directives to pass data to map or split_clients module.
For example, using the $geoip_city_continent_code
variable of the geoip_city
directive, and the map
module, you can create another variable whose value will be the closest server basing on a continent location:
...
map $geoip_city_continent_code $nearest_server {
default default {};
EU eu;
NA na;
AS as;
AF af;
...
Then you can choose an upstream server basing on the value passed in the $nearest_server
variable:
...
server {
listen 12346;
proxy_pass $nearest_server;
}
upstream eu {
server eu1.example.com:12345;
server eu2.example.com:12345;
}
upstream na {
server na1.example.com:12345;
server na2.example.com:12345;
}
...
It the continent is Europe, then the value of the $nearest_server
will be eu
, and the connection will be passed to the eu
upstream via the proxy_pass
directive.
This example can be applied to both http and stream contexts.
# can be either "http {" or "stream {"
...
geoip_country GeoIP/GeoIP.dat;
geoip_city GeoIP/GeoLiteCity.dat;
map $geoip_city_continent_code $nearest_server {
default default {};
EU eu;
NA na;
AS as;
AF af;
server {
listen 12346;
proxy_pass $nearest_server;
}
upstream eu {
server eu1.example.com:12345;
server eu2.example.com:12345;
}
upstream na {
server na1.example.com:12345;
server na2.example.com:12345;
}
}
In this example, the IP address will be checked in the GeoLiteCity.dat
database, the result will be written to the $geoip_city_continent_code
variable. NGINX will match the value of the variable against values in the map
directive and white the result in the custom variable, in our example $nearest_server
. Basing on the value of the $nearest_server
, the proxy_pass
directive will choose a corresponding upstream server.